home *** CD-ROM | disk | FTP | other *** search
- Subject: v14i102: Dial out and terminal emulator, Part04/06
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: fthood!egray
- Posting-number: Volume 14, Issue 102
- Archive-name: pcomm/part04
-
-
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create:
- # input.c
- # line_set.c
- # list_dir.c
- # ls_menu.c
- # m_lib.c
- # main.c
- # n_shell.c
- # p_lib.c
- # pexit.c
- # port.c
- # redial.c
- export PATH; PATH=/bin:/usr/bin:$PATH
- echo shar: "extracting 'input.c'" '(6599 characters)'
- if test -f 'input.c'
- then
- echo shar: "will not over-write existing file 'input.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'input.c'
- X/*
- X * The input routines. These routines are run as a child process to the
- X * main pcomm program.
- X */
- X
- X#define LPR "/usr/bin/lpr"
- X
- X#define MAX_ROW 64
- X#define MAX_COL 128
- X
- X#include <stdio.h>
- X#include <signal.h>
- X#include <setjmp.h>
- X
- Xjmp_buf i_jmp;
- Xunsigned char vs[MAX_ROW][MAX_COL+2];
- Xint row, col;
- X
- X/*
- X * Read the serial port and write the characters to the screen. Watch
- X * for signals from the parent process to toggle the fancy options.
- X * Writes the characters received to a virtual screen buffer.
- X */
- Xint
- Xinput(fd, add_lf, log, print, max_row, max_col, vs_file, log_file)
- Xint fd, add_lf, log, print, max_row, max_col;
- Xchar *vs_file, *log_file;
- X{
- X FILE *logfp, *lprfp, *popen();
- X int hold, skip_row, got_sig();
- X unsigned char c;
- X char lf=10;
- X void _exit();
- X /* set the trap for the signals */
- X signal(SIGALRM, SIG_IGN);
- X signal(SIGUSR1, got_sig);
- X signal(SIGUSR2, got_sig);
- X signal(SIGINT, got_sig);
- X signal(SIGTERM, got_sig);
- X /* resonable limits */
- X if (max_row > MAX_ROW)
- X max_row = MAX_ROW;
- X if (max_col > MAX_COL)
- X max_col = MAX_COL;
- X /* read previous screen */
- X if (!access(vs_file, 0)) {
- X read_vs(vs_file, max_row, max_col);
- X skip_row = 0;
- X }
- X else
- X skip_row = 1;
- X
- X hold = 0;
- X /* startup file pointers */
- X if (print)
- X lprfp = popen(LPR, "w");
- X
- X if (log && strcmp(log_file, "NOT_DEFINED"))
- X logfp = fopen(log_file, "a");
- X
- X switch(setjmp(i_jmp)) {
- X case 0: /* no signal */
- X break;
- X case 1: /* toggle the data logging */
- X signal(SIGUSR1, got_sig);
- X if (!strcmp(log_file, "NOT_DEFINED")) {
- X log = 0;
- X break;
- X }
- X log = log ? 0 : 1;
- X if (log)
- X logfp = fopen(log_file, "a");
- X else
- X fclose(logfp);
- X break;
- X case 2: /* toggle the printer */
- X signal(SIGUSR2, got_sig);
- X print = print ? 0 : 1;
- X if (print)
- X lprfp = popen(LPR, "w");
- X else {
- X putc(014, lprfp);
- X pclose(lprfp);
- X }
- X break;
- X case 3: /* suspend the input */
- X signal(SIGINT, got_sig);
- X hold = hold ? 0 : 1;
- X if (hold)
- X write_vs(vs_file, max_row, max_col);
- X break;
- X case 4: /* cleanup and go home */
- X signal(SIGTERM, got_sig);
- X if (log)
- X fclose(logfp);
- X if (print) {
- X putc(014, lprfp);
- X pclose(lprfp);
- X }
- X _exit(0);
- X break;
- X }
- X /* any signal will awaken pause() */
- X if (hold)
- X pause();
- X /* clear if vs_path doesn't exist */
- X if (access(vs_file, 0))
- X clear_vs(max_row, max_col);
- X /*
- X * The very first screen we see after dialing has the "Connected to..."
- X * message at row 0, therefore we start our virtual screen at row 1.
- X */
- X if (skip_row) {
- X skip_row = 0;
- X row = 1;
- X }
- X
- X while(1) {
- X if (read(fd, (char *) &c, 1) <= 0)
- X continue;
- X /* send to logfile */
- X if (log) {
- X if (c == 015 && add_lf)
- X fwrite(&lf, 1, 1, logfp);
- X /* no carriage returns in logfile */
- X if (c != 015)
- X fwrite((char *) &c, 1, 1, logfp);
- X }
- X /* send to printer too ? */
- X if (print)
- X fwrite((char *) &c, 1, 1, lprfp);
- X
- X /* put a char in virtual screen */
- X putchar_vs(c, add_lf, max_row, max_col);
- X
- X write(1, (char *) &c, 1);
- X /* add LF to CR ? */
- X if (add_lf)
- X write(1, &lf, 1);
- X }
- X}
- X
- X/*
- X * Figure out which signal we just received, and fix the return code of
- X * the setjmp function above to the proper value.
- X */
- X
- Xint
- Xgot_sig(sig)
- Xint sig;
- X{
- X void longjmp();
- X
- X switch(sig) {
- X case SIGUSR1:
- X longjmp(i_jmp, 1);
- X case SIGUSR2:
- X longjmp(i_jmp, 2);
- X case SIGINT:
- X longjmp(i_jmp, 3);
- X case SIGTERM:
- X longjmp(i_jmp, 4);
- X }
- X}
- X
- X/*
- X * Put a character in the virtual screen. This routine saves incoming
- X * character in a two dimensional buffer designed to mimic the real
- X * screen. CURRENTLY DOES NOT UNDERSTAND ESCAPE SEQUENCES!
- X */
- X
- Xint
- Xputchar_vs(c, add_lf, max_row, max_col)
- Xunsigned char c;
- Xint add_lf, max_row, max_col;
- X{
- X int tab_stop;
- X
- X switch(c) {
- X case 8: /* destructive back space */
- X col--;
- X if (col < 0)
- X col = 0;
- X vs[row][col] = ' ';
- X break;
- X case 9: /* tab character */
- X tab_stop = col + 8 - (col % 8);
- X /* if wrap around */
- X if (tab_stop >= max_col) {
- X /* spaces up to eol */
- X for (; col<max_col; col++)
- X vs[row][col] = ' ';
- X row++;
- X if (row >= max_row)
- X scroll_vs(max_row, max_col);
- X
- X /* the remainder of the tab */
- X col = tab_stop - max_col;
- X }
- X else {
- X for (; col<tab_stop; col++)
- X vs[row][col] = ' ';
- X }
- X break;
- X case 13: /* carriage return */
- X col = 0;
- X if (!add_lf)
- X break;
- X /* fall thru...*/
- X case 10: /* line feed */
- X row++;
- X if (row >= max_row)
- X scroll_vs(max_row, max_col);
- X break;
- X default: /* a normal character */
- X vs[row][col] = c;
- X col++;
- X /* wrap around */
- X if (col >= max_col) {
- X col = 0;
- X row++;
- X if (row >= max_row)
- X scroll_vs(max_row, max_col);
- X }
- X break;
- X }
- X return;
- X}
- X
- X/*
- X * Save the virtual screen to a file.
- X */
- X
- Xint
- Xwrite_vs(vs_file, max_row, max_col)
- Xchar *vs_file;
- Xint max_row, max_col;
- X{
- X FILE *fp;
- X int i;
- X
- X if (!(fp = fopen(vs_file, "w")))
- X return(1);
- X /* current x y coordinates */
- X fprintf(fp, "%d,%d\n", row, col);
- X
- X for (i=0; i<max_row; i++) {
- X vs[i][max_col] = NULL;
- X fprintf(fp, "%s\n", vs[i]);
- X }
- X fclose(fp);
- X return(0);
- X}
- X
- X/*
- X * Get the virtual screen image from the file. Since input() gets
- X * killed from time to time, the vs_path file is the only way to retain
- X * the screen image.
- X */
- X
- Xint
- Xread_vs(vs_file, max_row, max_col)
- Xchar *vs_file;
- Xint max_row, max_col;
- X{
- X FILE *fp;
- X int i;
- X char buf[10];
- X /* in case the fopen fails... */
- X row = 0;
- X col = 0;
- X /* not guaranteed to exist yet */
- X if (!(fp = fopen(vs_file, "r")))
- X return(1);
- X /* get the x, y coordinates */
- X fgets(buf, 10, fp);
- X scanf(buf, "%d,%d\n", &row, &col);
- X
- X /* read the file into the vs array */
- X for (i=0; i<max_row; i++) {
- X fgets((char *) vs[i], MAX_COL+2, fp);
- X vs[i][max_col] = NULL;
- X }
- X
- X fclose(fp);
- X return(0);
- X}
- X
- X/*
- X * If the user clears the screen with the ^A-C command, the input
- X * has to be in sync. The way it gets notified, is that the vs_path
- X * file disappears.
- X */
- X
- Xint
- Xclear_vs(max_row, max_col)
- Xint max_row, max_col;
- X{
- X int i, j;
- X
- X for (i=0; i<max_row; i++) {
- X vs[i][max_col] = NULL;
- X for (j=0; j<max_col; j++)
- X vs[i][j] = ' ';
- X }
- X /* home the "cursor" */
- X row = 0;
- X col = 0;
- X return(0);
- X}
- X
- X/*
- X * Do a software scroll on the virtual screen. Does not alter the
- X * 'col' variable.
- X */
- X
- Xint
- Xscroll_vs(max_row, max_col)
- Xint max_row, max_col;
- X{
- X int i, j;
- X char *strcpy();
- X /* move 'em up 1 line */
- X for (i=0; i<max_row-1; i++)
- X strcpy((char *) vs[i], (char *) vs[i+1]);
- X /* clear the bottom line */
- X for (j=0; j<max_col; j++)
- X vs[max_row-1][j] = ' ';
- X
- X row = max_row -1;
- X return(0);
- X}
- SHAR_EOF
- if test 6599 -ne "`wc -c < 'input.c'`"
- then
- echo shar: "error transmitting 'input.c'" '(should have been 6599 characters)'
- fi
- fi
- echo shar: "extracting 'line_set.c'" '(2130 characters)'
- if test -f 'line_set.c'
- then
- echo shar: "will not over-write existing file 'line_set.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'line_set.c'
- X/*
- X * Change the communication line settings to the new values.
- X */
- X
- X#include <stdio.h>
- X#include <termio.h>
- X#include "dial_dir.h"
- X#include "param.h"
- X#include "status.h"
- X
- Xvoid
- Xline_set()
- X{
- X struct termio tbuf;
- X
- X /*
- X * The manual dial entry also serves to store the previous
- X * line settings. How else would the manual dial entry
- X * know what line setting to use?
- X */
- X if (dir->d_cur != 0) {
- X dir->baud[0] = dir->baud[dir->d_cur];
- X dir->parity[0] = dir->parity[dir->d_cur];
- X dir->dbits[0] = dir->dbits[dir->d_cur];
- X dir->sbits[0] = dir->sbits[dir->d_cur];
- X }
- X /* nothing to do! */
- X if (status->fd == -1)
- X return;
- X /* get the current settings */
- X ioctl(status->fd, TCGETA, &tbuf);
- X /* set some beginning values */
- X tbuf.c_cc[4] = 1;
- X tbuf.c_cc[5] = 0;
- X tbuf.c_oflag = 0;
- X tbuf.c_iflag = 0;
- X tbuf.c_cflag = (CREAD|HUPCL);
- X tbuf.c_lflag = 0;
- X
- X /*
- X * I don't think there's any need for output flow control... (I don't
- X * know about you guys, but I can't type faster than the host can
- X * receive!) Besides, the file transfers reset this anyway.
- X */
- X if (*param->flow == 'X')
- X tbuf.c_iflag |= IXOFF;
- X /* strip high bit ? */
- X if (*param->strip == 'Y')
- X tbuf.c_iflag |= ISTRIP;
- X /* the baud rate */
- X switch (dir->baud[dir->d_cur]) {
- X case 300:
- X tbuf.c_cflag |= B300;
- X break;
- X case 1200:
- X tbuf.c_cflag |= B1200;
- X break;
- X case 2400:
- X tbuf.c_cflag |= B2400;
- X break;
- X case 4800:
- X tbuf.c_cflag |= B4800;
- X break;
- X case 9600:
- X tbuf.c_cflag |= B9600;
- X break;
- X case 19200:
- X /*
- X * Be careful here... some systems use EXTA in lieu
- X * of B19200.
- X */
- X tbuf.c_cflag |= B19200;
- X break;
- X }
- X /* the parity */
- X switch (dir->parity[dir->d_cur]) {
- X case 'N':
- X break;
- X case 'O':
- X tbuf.c_cflag |= (PARENB|PARODD);
- X break;
- X case 'E':
- X tbuf.c_cflag |= PARENB;
- X break;
- X }
- X /* the data bits */
- X if (dir->dbits[dir->d_cur] == 8)
- X tbuf.c_cflag |= CS8;
- X else
- X tbuf.c_cflag |= CS7;
- X /* the stop bits */
- X if (dir->sbits[dir->d_cur] == 2)
- X tbuf.c_cflag |= CSTOPB;
- X
- X /* now set 'em! */
- X ioctl(status->fd, TCSETA, &tbuf);
- X ioctl(status->fd, TCFLSH, 2);
- X return;
- X}
- SHAR_EOF
- if test 2130 -ne "`wc -c < 'line_set.c'`"
- then
- echo shar: "error transmitting 'line_set.c'" '(should have been 2130 characters)'
- fi
- fi
- echo shar: "extracting 'list_dir.c'" '(1479 characters)'
- if test -f 'list_dir.c'
- then
- echo shar: "will not over-write existing file 'list_dir.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'list_dir.c'
- X/*
- X * Do a shell escape with an 'ls' command
- X */
- X
- X#include <stdio.h>
- X#include <curses.h>
- X#include "misc.h"
- X
- Xvoid
- Xlist_dir(fd)
- Xint fd;
- X{
- X WINDOW *ls_win, *newwin();
- X FILE *pfp, *native_popen();
- X int lines, oops;
- X char *ans, *cwd, *getcwd(), buf[200], *get_str();
- X
- X ls_win = newwin(6, 70, 8, 5);
- X
- X cwd = getcwd(buf, 200);
- X
- X mvwprintw(ls_win, 2, 4, "Current directory: %s", cwd);
- X mvwaddstr(ls_win, 3, 4, "File spec (wildcards allowed): ");
- X box(ls_win, '|', '-');
- X
- X mvwattrstr(ls_win, 0, 3, A_BOLD, " List Directory ");
- X wmove(ls_win, 3, 35);
- X wrefresh(ls_win);
- X
- X if ((ans = get_str(ls_win, 60, NULL, NULL)) == NULL) {
- X if (fd == -1) {
- X werase(ls_win);
- X wrefresh(ls_win);
- X }
- X delwin(ls_win);
- X return;
- X }
- X /* popen() an ls */
- X sprintf(buf, "ls -aC %s", ans);
- X pfp = native_popen(buf, "r");
- X /* make a bigger window */
- X werase(ls_win);
- X wrefresh(ls_win);
- X delwin(ls_win);
- X ls_win = newwin(LINES-1, COLS, 0, 0);
- X
- X oops = 0;
- X lines = 0;
- X while (fgets(buf, BUFSIZ, pfp) != NULL) {
- X waddstr(ls_win, buf);
- X lines++;
- X if (lines == LINES-2) {
- X lines = 0;
- X mvwaddstr(ls_win, LINES-2, 28, "Press any key for more");
- X wrefresh(ls_win);
- X if (wgetch(ls_win) == 27) {
- X oops++;
- X break;
- X }
- X werase(ls_win);
- X wrefresh(ls_win);
- X }
- X }
- X native_pclose(pfp);
- X
- X if (!oops) {
- X mvwaddstr(ls_win, LINES-2, 25, "Press any key to continue");
- X wrefresh(ls_win);
- X wgetch(ls_win);
- X }
- X if (fd == -1) {
- X werase(ls_win);
- X wrefresh(ls_win);
- X }
- X delwin(ls_win);
- X return;
- X}
- SHAR_EOF
- if test 1479 -ne "`wc -c < 'list_dir.c'`"
- then
- echo shar: "error transmitting 'list_dir.c'" '(should have been 1479 characters)'
- fi
- fi
- echo shar: "extracting 'ls_menu.c'" '(4820 characters)'
- if test -f 'ls_menu.c'
- then
- echo shar: "will not over-write existing file 'ls_menu.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'ls_menu.c'
- X/*
- X * Routines for displaying current line settings and prompting for changes.
- X */
- X
- X#include <stdio.h>
- X#include <curses.h>
- X#include "dial_dir.h"
- X#include "misc.h"
- X#include "param.h"
- X
- X/*
- X * Display the current line settings and prompt for changes. A return
- X * code of 1 means settings were changed.
- X */
- X
- Xint
- Xline_set_menu(fd)
- Xint fd;
- X{
- X WINDOW *l_win, *newwin();
- X int num, ret_code;
- X void disp_settings();
- X
- X l_win = newwin(20, 47, 0, 16);
- X
- X mvwattrstr(l_win, 1, 16, A_BOLD, "Line Settings");
- X waddstr(l_win, "\n----------------------------------------------");
- X mvwaddstr(l_win, 6, 5, "1) 300,E,7,1 7) 300,N,8,1");
- X mvwaddstr(l_win, 7, 5, "2) 1200,E,7,1 8) 1200,N,8,1");
- X mvwaddstr(l_win, 8, 5, "3) 2400,E,7,1 9) 2400,N,8,1");
- X mvwaddstr(l_win, 9, 5, "4) 4800,E,7,1 10) 4800,N,8,1");
- X mvwaddstr(l_win, 10, 5, "5) 9600,E,7,1 11) 9600,N,8,1");
- X mvwaddstr(l_win, 11, 5, "6) 19200,E,7,1 12) 19200,N,8,1");
- X mvwaddstr(l_win, 13, 4, "Parity Data Bits Stop Bits");
- X mvwaddstr(l_win, 14, 4, "13) Odd 14) 7 bits 16) 1 bit");
- X mvwaddstr(l_win, 15, 18, "15) 8 bits 17) 2 bits");
- X mvwaddstr(l_win, 17, 4, "18) Save Changes");
- X mvwattrstr(l_win, 17, 28, A_BOLD, "YOUR CHOICE:");
- X wmove(l_win, 17, 41);
- X box(l_win, '|', '-');
- X
- X mvwaddstr(l_win, 19, 14, " Press ESC to return ");
- X /* display current settings */
- X disp_settings(l_win);
- X wmove(l_win, 17, 41);
- X wrefresh(l_win);
- X /* get the options */
- X ret_code = 0;
- X while ((num = get_num(l_win, 2)) != -1) {
- X switch(num) {
- X case 1:
- X dir->baud[dir->d_cur] = 300;
- X dir->parity[dir->d_cur] = 'E';
- X dir->dbits[dir->d_cur] = 7;
- X dir->sbits[dir->d_cur] = 1;
- X break;
- X case 2:
- X dir->baud[dir->d_cur] = 1200;
- X dir->parity[dir->d_cur] = 'E';
- X dir->dbits[dir->d_cur] = 7;
- X dir->sbits[dir->d_cur] = 1;
- X break;
- X case 3:
- X dir->baud[dir->d_cur] = 2400;
- X dir->parity[dir->d_cur] = 'E';
- X dir->dbits[dir->d_cur] = 7;
- X dir->sbits[dir->d_cur] = 1;
- X break;
- X case 4:
- X dir->baud[dir->d_cur] = 4800;
- X dir->parity[dir->d_cur] = 'E';
- X dir->dbits[dir->d_cur] = 7;
- X dir->sbits[dir->d_cur] = 1;
- X break;
- X case 5:
- X dir->baud[dir->d_cur] = 9600;
- X dir->parity[dir->d_cur] = 'E';
- X dir->dbits[dir->d_cur] = 7;
- X dir->sbits[dir->d_cur] = 1;
- X break;
- X case 6:
- X dir->baud[dir->d_cur] = 19200;
- X dir->parity[dir->d_cur] = 'E';
- X dir->dbits[dir->d_cur] = 7;
- X dir->sbits[dir->d_cur] = 1;
- X break;
- X case 7:
- X dir->baud[dir->d_cur] = 300;
- X dir->parity[dir->d_cur] = 'N';
- X dir->dbits[dir->d_cur] = 8;
- X dir->sbits[dir->d_cur] = 1;
- X break;
- X case 8:
- X dir->baud[dir->d_cur] = 1200;
- X dir->parity[dir->d_cur] = 'N';
- X dir->dbits[dir->d_cur] = 8;
- X dir->sbits[dir->d_cur] = 1;
- X break;
- X case 9:
- X dir->baud[dir->d_cur] = 2400;
- X dir->parity[dir->d_cur] = 'N';
- X dir->dbits[dir->d_cur] = 8;
- X dir->sbits[dir->d_cur] = 1;
- X break;
- X case 10:
- X dir->baud[dir->d_cur] = 4800;
- X dir->parity[dir->d_cur] = 'N';
- X dir->dbits[dir->d_cur] = 8;
- X dir->sbits[dir->d_cur] = 1;
- X break;
- X case 11:
- X dir->baud[dir->d_cur] = 9600;
- X dir->parity[dir->d_cur] = 'N';
- X dir->dbits[dir->d_cur] = 8;
- X dir->sbits[dir->d_cur] = 1;
- X break;
- X case 12:
- X dir->baud[dir->d_cur] = 19200;
- X dir->parity[dir->d_cur] = 'N';
- X dir->dbits[dir->d_cur] = 8;
- X dir->sbits[dir->d_cur] = 1;
- X break;
- X case 13:
- X dir->parity[dir->d_cur] = 'O';
- X break;
- X case 14:
- X dir->dbits[dir->d_cur] = 7;
- X break;
- X case 15:
- X dir->dbits[dir->d_cur] = 8;
- X break;
- X case 16:
- X dir->sbits[dir->d_cur] = 1;
- X break;
- X case 17:
- X dir->sbits[dir->d_cur] = 2;
- X break;
- X case 18:
- X /* copy the current settings */
- X param->d_baud = dir->baud[dir->d_cur];
- X param->d_parity = dir->parity[dir->d_cur];
- X param->d_dbits = dir->dbits[dir->d_cur];
- X param->d_sbits = dir->sbits[dir->d_cur];
- X /*
- X * We've changed the values in memory even
- X * if the update fails.
- X */
- X if (update_param()) {
- X touchwin(l_win);
- X wrefresh(l_win);
- X }
- X break;
- X default:
- X beep();
- X }
- X ret_code++;
- X disp_settings(l_win);
- X mvwaddstr(l_win, 17, 41, " ");
- X wmove(l_win, 17, 41);
- X wrefresh(l_win);
- X }
- X if (fd == -1) {
- X werase(l_win);
- X wrefresh(l_win);
- X }
- X delwin(l_win);
- X return(ret_code);
- X}
- X
- X/*
- X * Display the current settings. Formats the entire string at one
- X * time, in case you've got a magic cookie terminal.
- X */
- X
- Xvoid
- Xdisp_settings(win)
- XWINDOW *win;
- X{
- X char buf[40];
- X extern int xmc;
- X
- X sprintf(buf, "Current Settings: %5d,%c,%d,%d", dir->baud[dir->d_cur],
- X dir->parity[dir->d_cur], dir->dbits[dir->d_cur],
- X dir->sbits[dir->d_cur]);
- X
- X if (xmc > 0) {
- X touchwin(win);
- X clear_line(win, 4, 8, 1);
- X wrefresh(win);
- X }
- X mvwattrstr(win, 4, 8, A_BOLD, buf);
- X return;
- X}
- SHAR_EOF
- if test 4820 -ne "`wc -c < 'ls_menu.c'`"
- then
- echo shar: "error transmitting 'ls_menu.c'" '(should have been 4820 characters)'
- fi
- fi
- echo shar: "extracting 'm_lib.c'" '(9489 characters)'
- if test -f 'm_lib.c'
- then
- echo shar: "will not over-write existing file 'm_lib.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'm_lib.c'
- X/*
- X * Routines to manipulate the pcomm.modem file
- X */
- X
- X#include <stdio.h>
- X#include "modem.h"
- X#include "status.h"
- X
- X/*
- X * Read the modem database file. Returns a pointer to a static area
- X * containing the MODEM structure. All modem entries and all tty entries
- X * are created reguardless of the number of physical entries in the file.
- X */
- X
- Xstruct MODEM *
- Xread_modem()
- X{
- X FILE *fp;
- X int i, tty, mod, line, oops, m_line, start, stop;
- X char *strdup(), buf[200], message[80], token[40], *str_tok(), *str;
- X char *temp_token, *t_sep, *m_sep, *m_letter;
- X static struct MODEM m;
- X void error_win();
- X extern char *null_ptr;
- X
- X if (!(fp = fopen(status->m_path, "r"))) {
- X sprintf(buf, "'%s' for read", status->m_path);
- X error_win(1, "Can't open modem file", buf);
- X }
- X
- X t_sep = ";;\n";
- X m_sep = ";;;;\n;;;;;\n;;;\n";
- X m_letter = "abc";
- X oops = 0;
- X tty = 0;
- X mod = 0;
- X line = 0;
- X m_line = 0;
- X while (fgets(buf, 200, fp) != NULL) {
- X line++;
- X if (tty >= NUM_TTY || mod >= NUM_MODEM)
- X break;
- X /* get the token */
- X if (!(temp_token = str_tok(buf, '='))) {
- X sprintf(message, "is missing a token at line %d", line);
- X oops++;
- X break;
- X }
- X if (*temp_token != 'T' && *temp_token != 'M') {
- X sprintf(message, "is corrupted at line %d", line);
- X oops++;
- X break;
- X }
- X /* the tty database */
- X if (*temp_token == 'T') {
- X /*
- X * This is similar to the "real" strtok() command
- X * but this one returns a null pointer on a missing
- X * attribute. Note the use of the field separator
- X * array.
- X */
- X for (i=0; i<3; i++) {
- X if (!(str = str_tok((char *) NULL, t_sep[i]))) {
- X sprintf(message, "is missing a parameter at line %d", line);
- X oops++;
- X break;
- X }
- X switch(i) {
- X case 0:
- X m.tty[tty] = strdup(str);
- X break;
- X case 1:
- X m.tname[tty] = strdup(str);
- X break;
- X case 2:
- X m.mbaud[tty] = atoi(str);
- X break;
- X }
- X }
- X if (oops)
- X break;
- X /* sanity checking */
- X sprintf(token, "TTY_%d", tty+1);
- X if (strcmp(token, temp_token)) {
- X sprintf(message, "is corrupted at line %d", line);
- X oops++;
- X break;
- X }
- X tty++;
- X continue;
- X }
- X /* the modem database */
- X else {
- X sprintf(token, "MODEM_%d%c", mod+1, m_letter[m_line]);
- X if (strcmp(token, temp_token)) {
- X sprintf(message, "is corrupted at line %d", line);
- X oops++;
- X break;
- X }
- X /*
- X * There are three lines to the modem database. They
- X * distinguished by the letters a, b, and, c appended
- X * to the entry number.
- X */
- X switch(m_line) {
- X case 0:
- X start = 0;
- X stop = 5;
- X break;
- X case 1:
- X start = 5;
- X stop = 11;
- X break;
- X case 2:
- X start = 11;
- X stop = 15;
- X break;
- X }
- X for (i=start; i<stop; i++) {
- X if (!(str = str_tok((char *) NULL, m_sep[i]))) {
- X sprintf(message, "is missing a parameter at line %d", line);
- X oops++;
- X break;
- X }
- X switch(i) {
- X case 0:
- X m.mname[mod] = strdup(str);
- X break;
- X case 1:
- X m.init[mod] = strdup(str);
- X break;
- X case 2:
- X m.dial[mod] = strdup(str);
- X break;
- X case 3:
- X m.suffix[mod] = strdup(str);
- X break;
- X case 4:
- X m.hangup[mod] = strdup(str);
- X break;
- X case 5:
- X m.con_3[mod] = strdup(str);
- X break;
- X case 6:
- X m.con_12[mod] = strdup(str);
- X break;
- X case 7:
- X m.con_24[mod] = strdup(str);
- X break;
- X case 8:
- X m.con_48[mod] = strdup(str);
- X break;
- X case 9:
- X m.con_96[mod] = strdup(str);
- X break;
- X case 10:
- X m.con_192[mod] = strdup(str);
- X break;
- X case 11:
- X m.no_con1[mod] = strdup(str);
- X break;
- X case 12:
- X m.no_con2[mod] = strdup(str);
- X break;
- X case 13:
- X m.no_con3[mod] = strdup(str);
- X break;
- X case 14:
- X m.no_con4[mod] = strdup(str);
- X break;
- X }
- X }
- X if (oops)
- X break;
- X m_line++;
- X if (m_line >= 3) {
- X m_line = 0;
- X mod++;
- X }
- X }
- X }
- X fclose(fp);
- X
- X if (oops) {
- X sprintf(buf, "Modem file '%s'", status->m_path);
- X error_win(1, buf, message);
- X }
- X m.t_entries = tty;
- X m.m_entries = mod;
- X m.t_cur = -1;
- X m.m_cur = -1;
- X /* fill in the rest */
- X for (; tty<NUM_TTY; tty++) {
- X m.tty[tty] = null_ptr;
- X m.tname[tty] = null_ptr;
- X m.mbaud[tty] = 0;
- X }
- X for (; mod<NUM_MODEM; mod++) {
- X m.mname[mod] = null_ptr;
- X m.init[mod] = null_ptr;
- X m.dial[mod] = null_ptr;
- X m.suffix[mod] = null_ptr;
- X m.hangup[mod] = null_ptr;
- X
- X m.con_3[mod] = null_ptr;
- X m.con_12[mod] = null_ptr;
- X m.con_24[mod] = null_ptr;
- X m.con_48[mod] = null_ptr;
- X m.con_96[mod] = null_ptr;
- X m.con_192[mod] = null_ptr;
- X
- X m.no_con1[mod] = null_ptr;
- X m.no_con2[mod] = null_ptr;
- X m.no_con3[mod] = null_ptr;
- X m.no_con4[mod] = null_ptr;
- X }
- X return(&m);
- X}
- X
- X/*
- X * Update the modem database. Other routines actually do the changes
- X * or deletions in memory. A return code of 1 means non-fatal error.
- X */
- X
- Xint
- Xupdate_modem()
- X{
- X FILE *fp;
- X char buf[80];
- X int i;
- X void error_win();
- X
- X /* open for write */
- X if (!(fp = fopen(status->m_path, "w"))) {
- X sprintf(buf, "'%s'", status->m_path);
- X error_win(0, "No write permission on modem file", buf);
- X return(1);
- X }
- X /* put back the tty entries */
- X for (i=0; i<modem->t_entries; i++)
- X fprintf(fp, "TTY_%d=%s;%s;%d\n", i+1, modem->tty[i],
- X modem->tname[i], modem->mbaud[i]);
- X
- X /* put back the modem entries */
- X for (i=0; i<modem->m_entries; i++) {
- X fprintf(fp, "MODEM_%da=%s;%s;%s;%s;%s\n", i+1, modem->mname[i],
- X modem->init[i], modem->dial[i], modem->suffix[i],
- X modem->hangup[i]);
- X
- X fprintf(fp, "MODEM_%db=%s;%s;%s;%s;%s;%s\n", i+1,
- X modem->con_3[i], modem->con_12[i], modem->con_24[i],
- X modem->con_48[i], modem->con_96[i], modem->con_192[i]);
- X
- X fprintf(fp, "MODEM_%dc=%s;%s;%s;%s\n", i+1, modem->no_con1[i],
- X modem->no_con2[i], modem->no_con3[i], modem->no_con4[i]);
- X }
- X
- X fclose(fp);
- X return(0);
- X}
- X
- X/*
- X * See if the new modem is already in the database. If it's not,
- X * then create a slot for it and update the modem->m_cur variable.
- X */
- X
- Xvoid
- Xcreate_modem(str)
- Xchar *str;
- X{
- X int i;
- X char *strdup(), buf[80];
- X void error_win(), free_ptr();
- X /* modem entry already exists? */
- X for (i=0; i<modem->m_entries; i++) {
- X if (!strcmp(str, modem->mname[i]))
- X return;
- X }
- X /* empty slot available? */
- X if (modem->m_entries == NUM_MODEM) {
- X sprintf(buf, "'%s'", status->m_path);
- X error_win(0, "No empty modem slots in", buf);
- X return;
- X }
- X /* create a new entry */
- X free_ptr(modem->mname[modem->m_entries]);
- X modem->mname[modem->m_entries] = strdup(str);
- X
- X /* update number of entries */
- X modem->m_entries++;
- X return;
- X}
- X
- X/*
- X * See if the modem names in the list still need to be in the database.
- X * If you find a "lost" entry, delete it and collapse the list.
- X */
- X
- Xvoid
- Xdelete_modem()
- X{
- X int i, j, match;
- X char *strdup();
- X void free_ptr();
- X extern char *null_ptr;
- X
- X for (i=0; i<modem->m_entries; i++) {
- X match = 0;
- X for (j=0; j<modem->t_entries; j++) {
- X if (!strcmp(modem->mname[i], modem->tname[j])) {
- X match = 1;
- X break;
- X }
- X }
- X /* found a "lost" modem name */
- X if (!match) {
- X for (j=i; j<modem->m_entries-1; j++) {
- X free_ptr(modem->mname[j]);
- X free_ptr(modem->init[j]);
- X free_ptr(modem->dial[j]);
- X free_ptr(modem->suffix[j]);
- X free_ptr(modem->hangup[j]);
- X
- X free_ptr(modem->con_3[j]);
- X free_ptr(modem->con_12[j]);
- X free_ptr(modem->con_24[j]);
- X free_ptr(modem->con_48[j]);
- X free_ptr(modem->con_96[j]);
- X free_ptr(modem->con_192[j]);
- X
- X free_ptr(modem->no_con1[j]);
- X free_ptr(modem->no_con2[j]);
- X free_ptr(modem->no_con3[j]);
- X free_ptr(modem->no_con4[j]);
- X
- X /* copy the info */
- X modem->mname[j] = strdup(modem->mname[j+1]);
- X modem->init[j] = strdup(modem->init[j+1]);
- X modem->dial[j] = strdup(modem->dial[j+1]);
- X modem->suffix[j] = strdup(modem->suffix[j+1]);
- X modem->hangup[j] = strdup(modem->hangup[j+1]);
- X
- X modem->con_3[j] = strdup(modem->con_3[j+1]);
- X modem->con_12[j] = strdup(modem->con_12[j+1]);
- X modem->con_24[j] = strdup(modem->con_24[j+1]);
- X modem->con_48[j] = strdup(modem->con_48[j+1]);
- X modem->con_96[j] = strdup(modem->con_96[j+1]);
- X modem->con_192[j] = strdup(modem->con_192[j+1]);
- X
- X modem->no_con1[j] = strdup(modem->no_con1[j+1]);
- X modem->no_con2[j] = strdup(modem->no_con2[j+1]);
- X modem->no_con3[j] = strdup(modem->no_con3[j+1]);
- X modem->no_con4[j] = strdup(modem->no_con4[j+1]);
- X }
- X j = modem->m_entries -1;
- X
- X free_ptr(modem->mname[j]);
- X free_ptr(modem->init[j]);
- X free_ptr(modem->dial[j]);
- X free_ptr(modem->suffix[j]);
- X free_ptr(modem->hangup[j]);
- X
- X free_ptr(modem->con_3[j]);
- X free_ptr(modem->con_12[j]);
- X free_ptr(modem->con_24[j]);
- X free_ptr(modem->con_48[j]);
- X free_ptr(modem->con_96[j]);
- X free_ptr(modem->con_192[j]);
- X
- X free_ptr(modem->no_con1[j]);
- X free_ptr(modem->no_con2[j]);
- X free_ptr(modem->no_con3[j]);
- X free_ptr(modem->no_con4[j]);
- X
- X /* create an empty entry */
- X modem->mname[j] = null_ptr;
- X modem->init[j] = null_ptr;
- X modem->dial[j] = null_ptr;
- X modem->suffix[j] = null_ptr;
- X modem->hangup[j] = null_ptr;
- X
- X modem->con_3[j] = null_ptr;
- X modem->con_12[j] = null_ptr;
- X modem->con_24[j] = null_ptr;
- X modem->con_48[j] = null_ptr;
- X modem->con_96[j] = null_ptr;
- X modem->con_192[j] = null_ptr;
- X
- X modem->no_con1[j] = null_ptr;
- X modem->no_con2[j] = null_ptr;
- X modem->no_con3[j] = null_ptr;
- X modem->no_con4[j] = null_ptr;
- X
- X /* update the counts */
- X modem->m_entries--;
- X if (modem->m_cur >= modem->m_entries)
- X modem->m_cur = -1;
- X return;
- X }
- X }
- X return;
- X}
- SHAR_EOF
- if test 9489 -ne "`wc -c < 'm_lib.c'`"
- then
- echo shar: "error transmitting 'm_lib.c'" '(should have been 9489 characters)'
- fi
- fi
- echo shar: "extracting 'main.c'" '(4860 characters)'
- if test -f 'main.c'
- then
- echo shar: "will not over-write existing file 'main.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'main.c'
- X/*
- X * Pcomm is a public domain telecommunication program for Unix
- X * designed to operate similar to the popular MSDOS program, ProComm.
- X * ProComm (TM) is copyrighted by Datastorm Technologies, Inc.
- X *
- X * Emmet P. Gray US Army, HQ III Corps & Fort Hood
- X * ...!ihnp4!uiucuxc!fthood!egray Attn: AFZF-DE-ENV
- X * Directorate of Engineering & Housing
- X * Environmental Management Office
- X * Fort Hood, TX 76544-5057
- X * Beta release 7 Feb 88
- X * Release 1.0 12 Mar 88
- X */
- X
- X#include <stdio.h>
- X#include <signal.h>
- X#include <curses.h>
- X#ifndef OLDCURSES
- X#include <term.h>
- X#endif /* OLDCURSES */
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#define MAIN
- X#include "dial_dir.h"
- X#include "modem.h"
- X#include "param.h"
- X#include "status.h"
- X
- X#ifdef OLDCURSES
- Xchar bp[1024];
- X#define cbreak crmode
- X#endif /* OLDCURSES */
- X
- Xstruct PARAM *param;
- Xstruct DIAL_DIR *dir;
- Xstruct STATUS *status;
- Xstruct MODEM *modem;
- Xint xmc;
- Xchar *null_ptr;
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int c, ret_code, i, code, quit();
- X char *mytty, *ttyname(), *term, *getenv(), *index, *strdup();
- X char *extra_dir, buf[80], message[80];
- X struct PARAM *read_param();
- X struct DIAL_DIR *read_dir();
- X struct STATUS *init();
- X struct MODEM *read_modem();
- X struct stat stbuf;
- X void exit(), error_win(), input_on(), free_ptr();
- X extern char *optarg;
- X#ifdef OLDCURSES
- X char *tgetstr(), ocbuf[20];
- X char *ocbufptr = ocbuf;
- X#endif /* OLDCURSES */
- X
- X signal(SIGINT, SIG_IGN);
- X signal(SIGQUIT, SIG_IGN);
- X signal(SIGTERM, quit);
- X signal(SIGHUP, quit);
- X
- X null_ptr = "";
- X index = NULL;
- X extra_dir = NULL;
- X /* the command line */
- X while ((c = getopt(argc, argv, "d:f:")) != EOF) {
- X switch (c) {
- X case 'd': /* the extra directory to search */
- X extra_dir = strdup(optarg);
- X break;
- X case 'f': /* the index into the dialing dir */
- X index = strdup(optarg);
- X break;
- X case '?': /* default */
- X fprintf(stderr, "Usage: pcomm [-d directory] [-f index]\n");
- X exit(1);
- X break;
- X }
- X }
- X /* get terminal type */
- X term = getenv("TERM");
- X if (term == NULL || *term == NULL) {
- X fprintf(stderr, "Windows not supported (TERM not defined)\n");
- X exit(1);
- X }
- X /* see if terminfo entry exists */
- X#ifdef OLDCURSES
- X ret_code = tgetent(bp, term);
- X#else /* OLDCURSES */
- X setupterm(term, 1, &ret_code);
- X#endif /* OLDCURSES */
- X if (ret_code != 1) {
- X fprintf(stderr, "Windows not supported (no terminfo data for '%s')\n", term);
- X exit(1);
- X }
- X /* minimum screen size */
- X#ifdef OLDCURSES
- X if (tgetnum("co") < 80 || tgetnum("li") < 24) {
- X#else /* OLDCURSES */
- X if (columns < 80 || lines < 24) {
- X#endif /* OLDCURSES */
- X fprintf(stderr, "Windows not supported (minimum 80x24 screen required)\n");
- X exit(1);
- X }
- X /* must have cursor movement */
- X#ifdef OLDCURSES
- X if (tgetstr("cm", &ocbufptr) == NULL) {
- X#else /* OLDCURSES */
- X if (cursor_address == NULL) {
- X#endif /* OLDCURSES */
- X fprintf(stderr, "Windows not supported (terminal too dumb)\n");
- X exit(1);
- X }
- X /* load magic cookie variable */
- X#ifdef OLDCURSES
- X xmc = tgetnum("sg");
- X#else /* OLDCURSES */
- X xmc = magic_cookie_glitch;
- X#endif /* OLDCURSES */
- X /* ok... now lets go! */
- X initscr();
- X nonl();
- X cbreak();
- X noecho();
- X
- X param = (struct PARAM *) NULL;
- X modem = (struct MODEM *) NULL;
- X dir = (struct DIAL_DIR *) NULL;
- X /* show the herald, return status */
- X status = init(extra_dir, index);
- X /* get 'msgs' status */
- X mytty = ttyname(0);
- X stat(mytty, &stbuf);
- X chmod(mytty, 0600);
- X status->msg = stbuf.st_mode & 0777;
- X /* read the support files */
- X param = read_param();
- X dir = read_dir();
- X modem = read_modem();
- X /* short-cut to dialing window ? */
- X code = 0;
- X if (index != NULL) {
- X for (i=1; i<dir->d_entries+1; i++) {
- X if (!strcmp(dir->index[i], index)) {
- X dir->q_num[0] = i;
- X dir->d_cur = i;
- X break;
- X }
- X }
- X /* if match is found */
- X if (dir->q_num[0] != -1)
- X code = dial_win();
- X else {
- X sprintf(buf, "Can't find index '%s' in dialing directory file", index);
- X sprintf(message, "'%s'", status->d_path);
- X error_win(0, buf, message);
- X }
- X free_ptr(index);
- X }
- X /* start terminal dialogue */
- X terminal(code);
- X exit(0);
- X}
- X
- X/*
- X * Something dreadful happened... Cleanup the mess we made with the
- X * tty driver and release the phone line.
- X */
- X
- Xint
- Xquit()
- X{
- X void cleanup();
- X
- X cleanup(1);
- X /* never returns... */
- X return(0);
- X}
- X
- X/*
- X * Check write permission with the real UID and GID. Returns a 0 on
- X * permission denied, 1 on OK, and 2 on OK-but the file already exists.
- X */
- X
- Xint
- Xcan_write(file)
- Xchar *file;
- X{
- X char *p, path[200], *strcpy(), *strrchr();
- X
- X p = strcpy(path, file);
- X /* dissect the path component */
- X if (p = strrchr(path, '/'))
- X *(p++) = NULL;
- X else
- X strcpy(path, ".");
- X /* if it already exists */
- X if (!access(file, 0)) {
- X if (!access(file, 2))
- X return(2);
- X return(0);
- X }
- X /* if path is writable */
- X if (!access(path, 2))
- X return(1);
- X return(0);
- X}
- SHAR_EOF
- if test 4860 -ne "`wc -c < 'main.c'`"
- then
- echo shar: "error transmitting 'main.c'" '(should have been 4860 characters)'
- fi
- fi
- echo shar: "extracting 'n_shell.c'" '(1369 characters)'
- if test -f 'n_shell.c'
- then
- echo shar: "will not over-write existing file 'n_shell.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'n_shell.c'
- X/*
- X * Spawn a 'native' shell. 'Native' means the shell found in the SHELL
- X * environmental variable.
- X */
- X
- X#include <stdio.h>
- X#include <signal.h>
- X#include <curses.h>
- X
- Xvoid
- Xnative_shell()
- X{
- X WINDOW *sh_win, *newwin();
- X int (*istat)(), (*qstat)(), status, pid, w;
- X char *shell, *shellpath, *getenv(), *strrchr();
- X unsigned int sleep();
- X void _exit();
- X /* a full window */
- X sh_win = newwin(LINES, COLS, 0, 0);
- X
- X clear_absolute(sh_win);
- X waddstr(sh_win, "Pcomm <=> Unix gateway, use ^D or 'exit' to return\n");
- X wrefresh(sh_win);
- X /* out of curses mode */
- X resetterm();
- X
- X shellpath = getenv("SHELL");
- X if (shellpath == NULL || *shellpath == NULL)
- X shellpath = "/bin/sh";
- X
- X shell = strrchr(shellpath, '/') + 1;
- X
- X if (!(pid = fork())) {
- X#ifdef SGID
- X setgid(getgid());
- X#endif /* SGID */
- X execl(shellpath, shell, "-i", 0);
- X _exit(1);
- X }
- X istat = signal(SIGINT, SIG_IGN);
- X qstat = signal(SIGQUIT, SIG_IGN);
- X
- X while ((w = wait(&status)) != pid && w != -1)
- X ;
- X
- X signal(SIGINT, istat);
- X signal(SIGQUIT, qstat);
- X /* back to curses mode */
- X fixterm();
- X sleep(1);
- X
- X clear_absolute(stdscr);
- X delwin(sh_win);
- X return;
- X}
- X
- X/*
- X * Clear the screen absolutely! It's incrediblely hard to get curses() to
- X * clear the screen when it thinks its already clear.
- X */
- X
- Xint
- Xclear_absolute(win)
- XWINDOW *win;
- X{
- X clearok(curscr, 1);
- X wrefresh(win);
- X clearok(curscr, 0);
- X return(0);
- X}
- SHAR_EOF
- if test 1369 -ne "`wc -c < 'n_shell.c'`"
- then
- echo shar: "error transmitting 'n_shell.c'" '(should have been 1369 characters)'
- fi
- fi
- echo shar: "extracting 'p_lib.c'" '(5786 characters)'
- if test -f 'p_lib.c'
- then
- echo shar: "will not over-write existing file 'p_lib.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'p_lib.c'
- X/*
- X * Routines to manipulate the pcomm.param file.
- X */
- X
- X#include <stdio.h>
- X#include "param.h"
- X#include "status.h"
- X
- X/*
- X * Read the parameter structure from the pcomm.param file. Returns a
- X * pointer to the PARAM structure. All errors are fatal.
- X */
- X
- Xstruct PARAM *
- Xread_param()
- X{
- X FILE *fp;
- X int i, oops;
- X char buf[80], *temp_token, *str, *strdup();
- X char message[80], *str_tok();
- X static char *token[NUM_PARAM] = {"D_BAUD", "D_PARITY", "D_DBITS",
- X "D_SBITS", "HOT", "ASCII_HOT", "D_DUPLEX", "FLOW", "CR_IN", "CR_OUT",
- X "LOGFILE", "DUMPFILE", "STRIP", "PAUSE_CHAR", "CR_CHAR", "CTRL_CHAR",
- X "ESC_CHAR", "ABORT", "CDELAY", "PAUSE", "LECHO", "EXPAND", "CR_DELAY",
- X "PACE", "CR_UP", "LF_UP", "TIMER", "CR_DN", "LF_DN", "LD_PLUS",
- X "LD_MINUS", "LD_AT", "LD_POUND"};
- X static struct PARAM p;
- X void error_win();
- X /* read permission already checked */
- X fp = fopen(status->p_path, "r");
- X
- X oops = 0;
- X for (i=0; i<NUM_PARAM; i++) {
- X if (fgets(buf, 80, fp) == NULL) {
- X sprintf(message, "is truncated at line %d", i+1);
- X oops++;
- X break;
- X }
- X /* parse the input line */
- X if (!(temp_token = str_tok(buf, '='))) {
- X sprintf(message, "is missing a token at line %d", i+1);
- X oops++;
- X break;
- X }
- X if (!(str = str_tok((char *) NULL, '\n'))) {
- X sprintf(message, "is missing a parameter at line %d", i+1);
- X oops++;
- X break;
- X }
- X /* sanity checking */
- X if (strcmp(temp_token, token[i])) {
- X sprintf(message, "is corrupted at line %d", i+1);
- X oops++;
- X break;
- X }
- X
- X switch(i) {
- X /* used in line_set_menu() */
- X case LINE_SET:
- X p.d_baud = atoi(str);
- X break;
- X case LINE_SET+1:
- X p.d_parity = *str;
- X break;
- X case LINE_SET+2:
- X p.d_dbits = atoi(str);
- X break;
- X case LINE_SET+3:
- X p.d_sbits = atoi(str);
- X break;
- X
- X /* used in term_setup() */
- X case TERM_SETUP:
- X p.hot = atoi(str);
- X break;
- X case TERM_SETUP+1:
- X p.ascii_hot = strdup(str);
- X break;
- X case TERM_SETUP+2:
- X p.d_duplex = strdup(str);
- X break;
- X case TERM_SETUP+3:
- X p.flow = strdup(str);
- X break;
- X case TERM_SETUP+4:
- X p.cr_in = strdup(str);
- X break;
- X case TERM_SETUP+5:
- X p.cr_out = strdup(str);
- X break;
- X
- X /* used in gen_setup() */
- X case GEN_SETUP:
- X p.logfile = strdup(str);
- X break;
- X case GEN_SETUP+1:
- X p.dumpfile = strdup(str);
- X break;
- X case GEN_SETUP+2:
- X p.strip = strdup(str);
- X break;
- X case GEN_SETUP+3:
- X p.pause_char = *str;
- X break;
- X case GEN_SETUP+4:
- X p.cr_char = *str;
- X break;
- X case GEN_SETUP+5:
- X p.ctrl_char = *str;
- X break;
- X case GEN_SETUP+6:
- X p.esc_char = *str;
- X break;
- X case GEN_SETUP+7:
- X p.abort = strdup(str);
- X break;
- X
- X /* used in gen_setup() delay_times() */
- X case DELAY_TIMES:
- X p.cdelay = atoi(str);
- X break;
- X case DELAY_TIMES+1:
- X p.pause = atoi(str);
- X break;
- X
- X /* used in ascii_xfer_setup() */
- X case ASCII_SETUP:
- X p.lecho = strdup(str);
- X break;
- X case ASCII_SETUP+1:
- X p.expand = strdup(str);
- X break;
- X case ASCII_SETUP+2:
- X p.cr_delay = atoi(str);
- X break;
- X case ASCII_SETUP+3:
- X p.pace = strdup(str);
- X break;
- X case ASCII_SETUP+4:
- X p.cr_up = strdup(str);
- X break;
- X case ASCII_SETUP+5:
- X p.lf_up = strdup(str);
- X break;
- X case ASCII_SETUP+6:
- X p.timer = atoi(str);
- X break;
- X case ASCII_SETUP+7:
- X p.cr_dn = strdup(str);
- X break;
- X case ASCII_SETUP+8:
- X p.lf_dn = strdup(str);
- X break;
- X
- X /* used in d_revise() */
- X case LD_CODES:
- X p.ld_plus = strdup(str);
- X break;
- X case LD_CODES+1:
- X p.ld_minus = strdup(str);
- X break;
- X case LD_CODES+2:
- X p.ld_at = strdup(str);
- X break;
- X case LD_CODES+3:
- X p.ld_pound = strdup(str);
- X break;
- X }
- X }
- X fclose(fp);
- X if (oops) {
- X sprintf(buf, "Parameter file '%s'", status->p_path);
- X error_win(1, buf, message);
- X }
- X return(&p);
- X}
- X
- X/*
- X * Write the updated param structure to disk. The values in memory should
- X * have already been "purified". Later, we'll update only the entries that
- X * have been explicitly asked for. A return code of 1 means non-fatal error.
- X */
- X
- Xint
- Xupdate_param()
- X{
- X FILE *fp;
- X char buf[80];
- X void error_win();
- X /* open for write */
- X if (!(fp = fopen(status->p_path, "w"))) {
- X sprintf(buf, "'%s'", status->p_path);
- X error_win(0, "No write permission on parameter file", buf);
- X return(1);
- X }
- X
- X fprintf(fp, "D_BAUD=%d\n", param->d_baud);
- X fprintf(fp, "D_PARITY=%c\n", param->d_parity);
- X fprintf(fp, "D_DBITS=%d\n", param->d_dbits);
- X fprintf(fp, "D_SBITS=%d\n", param->d_sbits);
- X fprintf(fp, "HOT=%d\n", param->hot);
- X fprintf(fp, "ASCII_HOT=%s\n", param->ascii_hot);
- X fprintf(fp, "D_DUPLEX=%s\n", param->d_duplex);
- X fprintf(fp, "FLOW=%s\n", param->flow);
- X fprintf(fp, "CR_IN=%s\n", param->cr_in);
- X fprintf(fp, "CR_OUT=%s\n", param->cr_out);
- X fprintf(fp, "LOGFILE=%s\n", param->logfile);
- X fprintf(fp, "DUMPFILE=%s\n", param->dumpfile);
- X fprintf(fp, "STRIP=%s\n", param->strip);
- X fprintf(fp, "PAUSE_CHAR=%c\n", param->pause_char);
- X fprintf(fp, "CR_CHAR=%c\n", param->cr_char);
- X fprintf(fp, "CTRL_CHAR=%c\n", param->ctrl_char);
- X fprintf(fp, "ESC_CHAR=%c\n", param->esc_char);
- X fprintf(fp, "ABORT=%s\n", param->abort);
- X fprintf(fp, "CDELAY=%d\n", param->cdelay);
- X fprintf(fp, "PAUSE=%d\n", param->pause);
- X fprintf(fp, "LECHO=%s\n", param->lecho);
- X fprintf(fp, "EXPAND=%s\n", param->expand);
- X fprintf(fp, "CR_DELAY=%d\n", param->cr_delay);
- X fprintf(fp, "PACE=%s\n", param->pace);
- X fprintf(fp, "CR_UP=%s\n", param->cr_up);
- X fprintf(fp, "LF_UP=%s\n", param->lf_up);
- X fprintf(fp, "TIMER=%d\n", param->timer);
- X fprintf(fp, "CR_DN=%s\n", param->cr_dn);
- X fprintf(fp, "LF_DN=%s\n", param->lf_dn);
- X fprintf(fp, "LD_PLUS=%s\n", param->ld_plus);
- X fprintf(fp, "LD_MINUS=%s\n", param->ld_minus);
- X fprintf(fp, "LD_AT=%s\n", param->ld_at);
- X fprintf(fp, "LD_POUND=%s\n", param->ld_pound);
- X
- X fclose(fp);
- X return(0);
- X}
- SHAR_EOF
- if test 5786 -ne "`wc -c < 'p_lib.c'`"
- then
- echo shar: "error transmitting 'p_lib.c'" '(should have been 5786 characters)'
- fi
- fi
- echo shar: "extracting 'pexit.c'" '(2142 characters)'
- if test -f 'pexit.c'
- then
- echo shar: "will not over-write existing file 'pexit.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'pexit.c'
- X/*
- X * Exit pcomm. A user requested abort. There are a lot of things to do
- X * before we exit!
- X */
- X
- X#include <stdio.h>
- X#include <curses.h>
- X#include "dial_dir.h"
- X#include "misc.h"
- X#include "param.h"
- X#include "status.h"
- X
- Xvoid
- Xpexit(fd)
- Xint fd;
- X{
- X WINDOW *ex_win, *newwin();
- X void cleanup(), status_line();
- X
- X ex_win = newwin(5, 33, 3, 7);
- X
- X box(ex_win, '|', '-');
- X mvwattrstr(ex_win, 0, 3, A_BOLD, " Exit ");
- X if (yes_prompt(ex_win, 2, 4, A_BLINK, "Exit to Unix")) {
- X status_line(" exiting");
- X cleanup(0);
- X }
- X if (fd == -1) {
- X werase(ex_win);
- X wrefresh(ex_win);
- X }
- X delwin(ex_win);
- X return;
- X}
- X
- X/*
- X * Do the cleanup detail before we exit.
- X */
- X
- Xvoid
- Xcleanup(val)
- Xint val;
- X{
- X void release_port(), input_off(), exit(), status_line();
- X char *ttyname();
- X /* kill the input routine */
- X input_off();
- X /* zap the virtual screen file */
- X unlink(status->vs_path);
- X /* release the port */
- X release_port(0);
- X /* erase the window we made */
- X touchwin(stdscr);
- X clear();
- X refresh();
- X endwin();
- X /* return the tty chmod */
- X chmod(ttyname(0), status->msg);
- X exit(val);
- X}
- X
- X/*
- X * Open a window to display an error message. Handles both fatal and
- X * non-fatal errors
- X */
- X
- Xvoid
- Xerror_win(code, line_one, line_two)
- Xint code;
- Xchar *line_one, *line_two;
- X{
- X WINDOW *e_win, *newwin();
- X void cleanup(), status_line();
- X
- X e_win = newwin(7, 70, 9, 5);
- X /* display the nasty note */
- X mvwaddstr(e_win, 2, 4, line_one);
- X mvwaddstr(e_win, 3, 4, line_two);
- X box(e_win, '|', '-');
- X
- X if (code) {
- X mvwattrstr(e_win, 0, 4, A_BOLD, " Error ");
- X mvwattrstr(e_win, 5, 24, A_BLINK, "Press any key to exit");
- X wmove(e_win, 5, 46);
- X }
- X else {
- X mvwattrstr(e_win, 0, 4, A_BOLD, " Warning ");
- X mvwattrstr(e_win, 5, 22, A_BLINK, "Press any key to continue");
- X wmove(e_win, 5, 48);
- X }
- X beep();
- X wrefresh(e_win);
- X
- X wgetch(e_win);
- X werase(e_win);
- X wrefresh(e_win);
- X delwin(e_win);
- X
- X if (code) {
- X /*
- X * Since this routine gets called if there is an error reading
- X * the support files, the dir and param structures can't be
- X * guaranteed to exist yet.
- X */
- X if (dir != NULL && param != NULL)
- X status_line(" exiting");
- X cleanup(code);
- X }
- X return;
- X}
- SHAR_EOF
- if test 2142 -ne "`wc -c < 'pexit.c'`"
- then
- echo shar: "error transmitting 'pexit.c'" '(should have been 2142 characters)'
- fi
- fi
- echo shar: "extracting 'port.c'" '(6122 characters)'
- if test -f 'port.c'
- then
- echo shar: "will not over-write existing file 'port.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'port.c'
- X/*
- X * Routines to get or release a tty port.
- X */
- X
- X#define LOCKDIR "/usr/spool/uucp"
- X#undef ASCII_PID
- X
- X#include <stdio.h>
- X#include <fcntl.h>
- X#include <termio.h>
- X#ifdef UNIXPC
- X#include <sys/phone.h>
- X#endif /* UNIXPC */
- X#include "dial_dir.h"
- X#include "modem.h"
- X#include "status.h"
- X
- Xint getty_status;
- X/*
- X * Finds a free (or requested) serial port. Creates a lock file to hold
- X * it for our use. Loads the modem database. A return code of 1 means
- X * all ports (or the requested port) are busy.
- X */
- X
- Xint
- Xget_port()
- X{
- X int i, j, k, progpid, fd, list[NUM_TTY];
- X char file[80], buf[80], message[80], *strdup();
- X void error_win(), line_set(), release_port(), send_str();
- X void free_ptr();
- X
- X /*
- X * If we already have a port, see if it is good enough for the
- X * current request.
- X */
- X if (status->fd != -1) {
- X if (!strcmp(dir->index[dir->d_cur], modem->tty[modem->t_cur]) ||
- X modem->mbaud[modem->t_cur] >= dir->baud[dir->d_cur]) {
- X /*
- X * Re-initialize the modem because the baud
- X * rate (or other parameters) may have changed.
- X */
- X line_set();
- X send_str(modem->init[modem->m_cur]);
- X return(0);
- X }
- X }
- X release_port(1);
- X
- X /*
- X * See if you want a specific tty port. If the index field in the
- X * dialing directory is a valid device name, then use that tty.
- X */
- X sprintf(buf, "/dev/%s", dir->index[dir->d_cur]);
- X list[0] = -1;
- X /* if index is a valid device */
- X if (!access(buf, 0)) {
- X for (i=0; i<modem->t_entries; i++) {
- X /* and it exists in modem database */
- X if (!strcmp(dir->index[dir->d_cur], modem->tty[i])) {
- X list[0] = i;
- X list[1] = -1;
- X break;
- X }
- X }
- X }
- X
- X /*
- X * Create a list of acceptable ttys. It searches the tty database
- X * for the requested baud rate.
- X */
- X k = 0;
- X if (list[0] == -1) {
- X for (i=0; i<modem->t_entries; i++) {
- X /* skip ports with no modems */
- X if (!strcmp(modem->tname[i], "DIRECT"))
- X continue;
- X
- X /* can handle requested baud rate ? */
- X if (modem->mbaud[i] >= dir->baud[dir->d_cur])
- X list[k++] = i;
- X }
- X /* the end of list marker */
- X list[k] = -1;
- X }
- X /* empty list ? */
- X if (list[0] == -1) {
- X sprintf(message, "No modem at a %d baud rating exists in", dir->baud[dir->d_cur]);
- X sprintf(file, "modem file '%s'", status->m_path);
- X error_win(0, message, file);
- X return(1);
- X }
- X /* check the list for a free port */
- X i = 0;
- X while (list[i] != -1) {
- X /* create a lock file name */
- X sprintf(file, "%s/LCK..%s", LOCKDIR, modem->tty[list[i]]);
- X
- X /*
- X * See if the lock file exists... We DO NOT look to see
- X * if the pid in the file is still active. Maybe I'll
- X * change this later...
- X */
- X if (access(file, 0)) {
- X getty_status = set_getty(modem->tty[list[i]], 0);
- X
- X if ((fd = open(file, O_CREAT|O_WRONLY, 0666)) < 0) {
- X set_getty(modem->tty[list[i]], 1);
- X sprintf(buf, "'%s'", file);
- X error_win(1, "Can't create the lockfile", buf);
- X }
- X#ifdef ASCII_PID
- X sprintf(buf, "%10d\n", getpid());
- X write(fd, buf, 11);
- X#else /* ASCII_PID */
- X progpid = getpid();
- X write(fd, (char *)&progpid, sizeof(int));
- X#endif /* ASCII_PID */
- X close(fd);
- X /* store the new values */
- X free_ptr(status->lock_path);
- X status->lock_path = strdup(file);
- X modem->t_cur = list[i];
- X
- X /* open the device (hold DTR high) */
- X sprintf(buf, "/dev/%s", modem->tty[list[i]]);
- X if ((fd = open(buf, O_RDWR|O_NDELAY)) < 0) {
- X set_getty(modem->tty[list[i]], 1);
- X sprintf(file, "Can't open port '%s' for read and write", buf);
- X error_win(1, file, NULL);
- X }
- X
- X /* turn off the "no delay" mode */
- X fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) & ~O_NDELAY);
- X status->fd = fd;
- X /* change line settings */
- X line_set();
- X /* load the modem data base */
- X for (j=0; j<modem->m_entries; j++) {
- X if (!strcmp(modem->tname[list[i]], modem->mname[j])) {
- X modem->m_cur = j;
- X break;
- X }
- X }
- X /* initialize the modem */
- X send_str(modem->init[j]);
- X return(0);
- X }
- X i++;
- X }
- X error_win(0, "All ports are busy now, try again later", NULL);
- X return(1);
- X}
- X
- X/*
- X * Release the port. Closes the file descriptor and removes the
- X * lock file
- X */
- X
- Xvoid
- Xrelease_port(verbose)
- Xint verbose;
- X{
- X char buf[80];
- X extern char *null_ptr;
- X void free_ptr(), hang_up();
- X
- X /*
- X * The modem structure can't be guaranteed to exist yet. For example,
- X * an error in reading one of the other support files would cause
- X * this routine to be used before the MODEM structure gets allocated.
- X */
- X if (modem == NULL)
- X return;
- X /* close the port */
- X if (status->fd != -1) {
- X ioctl(status->fd, TCFLSH, 2);
- X /*
- X * Since HUPCL is set, the close() should drop the DTR and
- X * hang up the modem (provided you've got the modem to
- X * respond to DTR). Since this is not guaranteed, we send
- X * the hangup string first.
- X */
- X hang_up(verbose);
- X close(status->fd);
- X }
- X /* remove the lock */
- X if (*status->lock_path != NULL) {
- X if (unlink(status->lock_path)) {
- X sprintf(buf, "'%s'", status->lock_path);
- X error_win(0, "Can't remove the lock file", buf);
- X }
- X free_ptr(status->lock_path);
- X status->lock_path = null_ptr;
- X }
- X /* turn the getty back on? */
- X if (getty_status)
- X set_getty(modem->tty[modem->t_cur], 1);
- X /* cleanup the structure */
- X status->fd = -1;
- X modem->m_cur = -1;
- X modem->t_cur = -1;
- X return;
- X}
- X
- X/*
- X * Turn the /etc/getty on or off for the specified port. A return code
- X * of 1 means that the getty was on. Systems with uugetty or dedicated
- X * dialout ports won't need this routine.
- X */
- X
- Xint
- Xset_getty(tty, on)
- Xchar *tty;
- Xint on;
- X{
- X#ifdef UNIXPC
- X int i, ret_code;
- X char buf[40];
- X unsigned int sleep();
- X /* the last three characters */
- X i = strlen(tty) -3;
- X
- X ret_code = 0;
- X if (on) {
- X sprintf(buf, "setgetty %s 1", tty+i);
- X system(buf);
- X }
- X else {
- X sprintf(buf, "setgetty %s 0", tty+i);
- X if (system(buf) == 512)
- X ret_code = 1;
- X sleep(1);
- X }
- X return(ret_code);
- X#else /* UNIXPC */
- X /*
- X * If you don't have one of these cute little routines, you
- X * might wanna write one. It should check for an existing lock
- X * file, edit the /etc/inittab file, and issue an init -q.
- X * Obviously the program would be suid to root.
- X */
- X return(0);
- X#endif /* UNIXPC */
- X}
- SHAR_EOF
- if test 6122 -ne "`wc -c < 'port.c'`"
- then
- echo shar: "error transmitting 'port.c'" '(should have been 6122 characters)'
- fi
- fi
- echo shar: "extracting 'redial.c'" '(2216 characters)'
- if test -f 'redial.c'
- then
- echo shar: "will not over-write existing file 'redial.c'"
- else
- sed 's/^X//' << \SHAR_EOF > 'redial.c'
- X/*
- X * The redial option (actually a misnomer, it's really a queuing system).
- X * We expect a space-separated list of dialing directory entries (although
- X * new users always try to put in a phone number). A return code of 1
- X * means we're ready to dial.
- X */
- X
- X#include <stdio.h>
- X#include <curses.h>
- X#include "dial_dir.h"
- X#include "misc.h"
- X
- Xint
- Xredial(fd)
- Xint fd;
- X{
- X WINDOW *rd_win, *newwin();
- X char *ans, *entry, *get_str(), *strchr(), *strtok();
- X int i, oops, number, ret_code;
- X
- X rd_win = newwin(6, 70, 5, 5);
- X
- X mvwaddstr(rd_win, 4, 23, "(CR for previous numbers)");
- X mvwaddstr(rd_win, 2, 4, "Directory Entry Number(s): ");
- X box(rd_win, '|', '-');
- X
- X mvwattrstr(rd_win, 0, 3, A_BOLD, " Redial Queue ");
- X wmove(rd_win, 2, 31);
- X wrefresh(rd_win);
- X /* get the string of numbers */
- X ret_code = 0;
- X while ((ans = get_str(rd_win, 35, "0123456789+-@# ", NULL)) != NULL) {
- X oops = 0;
- X if (*ans == NULL) {
- X /* use previous queue */
- X if (dir->q_num[0] != -1) {
- X ret_code = 1;
- X break;
- X }
- X /* there is no previous queue */
- X beep();
- X mvwattrstr(rd_win, 3, 4, A_BOLD, "No previous numbers");
- X wrefresh(rd_win);
- X wait_key(rd_win, 3);
- X clear_line(rd_win, 3, 4, 1);
- X wmove(rd_win, 2, 31);
- X wrefresh(rd_win);
- X continue;
- X }
- X /* parse the queue values */
- X entry = strtok(ans, " ");
- X for (i=0; i<NUM_QUEUE; i++) {
- X if (*entry == NULL) {
- X dir->q_num[i] = -1;
- X continue;
- X }
- X /* is there a LD code ? */
- X dir->q_ld[i] = NULL;
- X if (strchr("+-@#", *entry)) {
- X dir->q_ld[i] = *entry;
- X entry++;
- X }
- X
- X /*
- X * Zero is valid here, because it means use
- X * the current entry information.
- X */
- X number = atoi(entry);
- X if (number < -1 || number > NUM_DIR) {
- X beep();
- X mvwattrstr(rd_win, 3, 4, A_BOLD, "Invalid directory entry number");
- X wrefresh(rd_win);
- X wait_key(rd_win, 3);
- X clear_line(rd_win, 3, 4, 1);
- X clear_line(rd_win, 2, 31, 1);
- X wrefresh(rd_win);
- X oops++;
- X break;
- X }
- X /* store the number in the queue */
- X dir->q_num[i] = number;
- X entry = strtok((char *) NULL, " ");
- X }
- X if (oops)
- X continue;
- X ret_code = 1;
- X break;
- X }
- X if (fd == -1) {
- X werase(rd_win);
- X wrefresh(rd_win);
- X }
- X delwin(rd_win);
- X return(ret_code);
- X}
- SHAR_EOF
- if test 2216 -ne "`wc -c < 'redial.c'`"
- then
- echo shar: "error transmitting 'redial.c'" '(should have been 2216 characters)'
- fi
- fi
- exit 0
- # End of shell archive
-
-
-